package com.the_last.listener;

import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.read.listener.ReadListener;
import com.the_last.pojo.dto.ProductImportDTO;
import com.the_last.pojo.po.Product;
import com.the_last.pojo.po.ProductCategory;
import com.the_last.service.ProductCategoryService;
import com.the_last.service.ProductService;
import com.the_last.utils.Result;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 商品导入Excel监听器（优化版）
 * 先批量读取所有数据，然后一次性查询数据库进行比对
 */
@Slf4j
public class ProductImportListener implements ReadListener<ProductImportDTO> {
    
    private final ProductService productService;
    private final ProductCategoryService productCategoryService;
    
    // 批量数据容器
    private final List<ProductImportDTO> allImportData = new ArrayList<>();
    // 记录文件内商品名称，自动去重
    private final Set<String> fileProductNames = new HashSet<>();
    /**
     * -- GETTER --
     * 获取错误信息列表
     */
    @Getter
    private final List<String> errorMessages = new CopyOnWriteArrayList<>();
    private final Map<String, Integer> categoryNameToIdMap = new HashMap<>();
    
    /**
     * -- GETTER --
     * 获取有效产品列表
     */
    // 处理结果
    @Getter
    private final List<Product> validProducts = new ArrayList<>();
    
    public ProductImportListener(ProductService productService, ProductCategoryService productCategoryService) {
        this.productService = productService;
        this.productCategoryService = productCategoryService;
        initCategoryMap();
    }
    
    /**
     * 初始化分类映射
     */
    private void initCategoryMap() {
        try {
            List<ProductCategory> categories = productCategoryService.list();
            for (ProductCategory category : categories) {
                categoryNameToIdMap.put(category.getName(), category.getId());
            }
        } catch (Exception e) {
            log.error("初始化商品分类映射失败", e);
        }
    }
    
    @Override
    public void invoke(ProductImportDTO data, AnalysisContext context) {
        int currentRowNum = context.readRowHolder().getRowIndex() + 1; // Excel行号从1开始
        
        // 简单的非空校验，详细校验放到doAfterAllAnalysed中批量处理
        if (data != null) {
            // 记录行号用于错误提示
            data.setRowNumber(currentRowNum);
            allImportData.add(data);
            
            // 如果商品名称不为空，加入Set自动去重
            if (StringUtils.hasText(data.getName())) {
                fileProductNames.add(data.getName().trim());
            }
        }
    }
    
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("Excel数据读取完成，共读取{}行数据，开始批量处理...", allImportData.size());
        
        try {
            // 1. 批量获取数据库中现有的商品名称（优先使用缓存）
            Set<String> existingProductNames = getExistingProductNames();
            log.info("获取到{}个现有商品名称（优先从缓存获取）", existingProductNames.size());
            
            // 2. 使用Stream批量处理和校验数据
            processBatchData(existingProductNames);
            
            // 3. 批量保存有效数据
            if (!validProducts.isEmpty()) {
                productService.saveBatch(validProducts);
                log.info("批量保存商品数据成功，共保存{}条", validProducts.size());
            }
            
            log.info("Excel数据处理完成，成功{}条，失败{}条", validProducts.size(), errorMessages.size());
            
        } catch (Exception e) {
            log.error("批量处理数据时发生异常", e);
            errorMessages.add("批量处理数据时发生异常：" + e.getMessage());
        }
    }
    
    /**
     * 批量获取数据库中现有的商品名称（优化：使用缓存）
     */
    private Set<String> getExistingProductNames() {
        try {
            // 使用缓存服务获取商品列表，性能更优
            Result<List<Product>> result = productService.getProductListWithCache(false);
            if (result.getCode() == 200 && result.getData() != null) {
                return result.getData().stream()
                        .map(Product::getName)
                        .filter(Objects::nonNull)
                        .map(String::trim)
                        .collect(Collectors.toSet());
            }
            return Collections.emptySet();
        } catch (Exception e) {
            log.error("从缓存获取商品名称失败", e);
            return Collections.emptySet();
        }
    }
    
    /**
     * 使用Stream批量处理数据（简化版）
     * 只检测数据库冲突
     */
    private void processBatchData(Set<String> existingProductNames) {
        // 直接使用fileProductNames与existingProductNames求交集，找出数据库冲突
        Set<String> conflictNames = fileProductNames.stream()
                .filter(existingProductNames::contains)
                .collect(Collectors.toSet());
        
        log.info("检测到数据库冲突{}个", conflictNames.size());
        
        // 使用Stream并行处理每行数据
        allImportData.parallelStream().forEach(data -> {
            String validationError = validateDataBatch(data, conflictNames);
            if (validationError != null) {
                errorMessages.add(String.format("第%d行：%s", data.getRowNumber(), validationError));
            } else {
                Product product = convertToProduct(data);
                validProducts.add(product);
            }
        });
    }
    
    /**
     * 批量数据校验（简化版）
     * 只检测数据库冲突
     */
    private String validateDataBatch(ProductImportDTO data, Set<String> conflictNames) {
        // 商品名称校验
        if (!StringUtils.hasText(data.getName())) {
            return "商品名称不能为空";
        }
        if (data.getName().length() > 100) {
            return "商品名称长度不能超过100个字符";
        }
        
        String trimmedName = data.getName().trim();
        
        // 检测数据库中是否已存在
        if (conflictNames.contains(trimmedName)) {
            return "商品名称已存在：" + trimmedName + "，请使用编辑功能更新或修改商品名称";
        }
        
        // 商品分类校验
        if (!StringUtils.hasText(data.getCategoryName())) {
            return "商品分类不能为空";
        }
        if (!categoryNameToIdMap.containsKey(data.getCategoryName())) {
            return "商品分类不存在：" + data.getCategoryName() + "，可用分类：" + String.join(", ", categoryNameToIdMap.keySet());
        }
        
        // 商品价格校验
        if (data.getCurrentPrice() == null) {
            return "商品价格不能为空";
        }
        if (data.getCurrentPrice().compareTo(BigDecimal.ZERO) < 0) {
            return "商品价格不能为负数";
        }
        if (data.getCurrentPrice().compareTo(new BigDecimal("999999.99")) > 0) {
            return "商品价格不能超过999999.99";
        }
        
        // 库存数量校验
        if (data.getStock() == null) {
            return "库存数量不能为空";
        }
        if (data.getStock() < 0) {
            return "库存数量不能为负数";
        }
        if (data.getStock() > 999999) {
            return "库存数量不能超过999999";
        }
        
        return null; // 校验通过
    }
    
    /**
     * 转换为Product实体
     */
    private Product convertToProduct(ProductImportDTO data) {
        Product product = new Product();
        product.setName(data.getName().trim());
        product.setCategoryId(categoryNameToIdMap.get(data.getCategoryName()));
        product.setCurrentPrice(data.getCurrentPrice());
        product.setStock(data.getStock());
        product.setSales(0); // 新商品销量为0
        product.setDeleted(0); // 正常状态
        
        return product;
    }
    
}